package com.bestcem.xm.award.dao.impl.mysql;

import com.alibaba.fastjson.JSON;
import com.bestcem.xm.award.dao.DrawRecordDao;
import com.bestcem.xm.award.dao.mapper.AwardRecordMapper;
import com.bestcem.xm.award.dao.mapper.query.RecordQuery;
import com.bestcem.xm.award.entity.mysql.AwardRecordEntity;
import com.bestcem.xm.award.entity.pojo.AwardRecordDO;
import com.bestcem.xm.award.enums.AwardIssueStatusEnum;
import com.bestcem.xm.award.enums.AwardLevelEnum;
import com.bestcem.xm.award.enums.RecordStatusEnum;
import com.bestcem.xm.award.grpc.service.param.draw.*;
import com.bestcem.xm.award.service.dto.draw.AwardDetailDTO;
import com.bestcem.xm.award.service.dto.draw.PageDTO;
import com.bestcem.xm.common.core.uitls.DateUtil;
import com.bestcem.xm.common.core.uitls.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * ds_award_record dao-mysql实现
 *
 * @author hang.li <hang.li@idiaoyan.com>
 * @version v1.0
 * @date 2021/9/18 16:58
 */
@Repository("recordDaoMysql")
@Slf4j
public class DrawRecordDaoImpl implements DrawRecordDao {

    @Resource
    private AwardRecordMapper recordMapper;

    @Override
    public AwardRecordDO getRecordByAwardPage(String awardPage) {
        RecordQuery query = new RecordQuery();
        query.setAwardPage(awardPage);
        return awardRecordEntityToDo(recordMapper.findOneByQueryParam(query));
    }

    @Override
    public long getAwardAlreadyDrawTotal(String awardId) {
        return recordMapper.getAwardAlreadyDrawTotal(awardId);
    }

    @Override
    public long getDrawTotalByPhone(String awardId, String phone) {
        return recordMapper.getDrawTotalByPhone(awardId, phone);
    }

    @Override
    public long getWinTotalByPhone(String awardId, String phone) {
        return recordMapper.getWinTotalByPhone(awardId, phone);
    }

    @Override
    public AwardRecordDO insertDrawRecord(AwardRecordDO awardRecord) {
        AwardRecordEntity recordEntity = new AwardRecordEntity();
        recordEntity.setRecordId(StringUtil.getId());
        recordEntity.setAwardId(awardRecord.getAwardId())
                .setDeliverId(awardRecord.getAward().getDeliverId())
                .setDeliverSource(awardRecord.getAward().getDeliverSource())
                .setDeliverName(awardRecord.getAward().getDeliverName())
                .setSurveyId(awardRecord.getAward().getSurveyId())
                .setSurveySeq(awardRecord.getAward().getSurveySeq())
                .setAwardPage(awardRecord.getAward().getAwardPage())
                .setPhone(awardRecord.getPhone())
                .setStatus(awardRecord.getStatus())
                .setCreateTime(DateUtil.getCommonDate())
                .setUpdateTime(DateUtil.getCommonDate());
        recordMapper.insertDrawRecord(recordEntity);
        return awardRecordEntityToDo(recordEntity);
    }

    @Override
    public AwardRecordDO getRecordByIdAndStatus(String recordId, Integer status) {
        RecordQuery query = new RecordQuery().setRecordId(recordId).setStatus(status);
        return awardRecordEntityToDo(recordMapper.findOneByQueryParam(query));
    }

    @Override
    public long updateWinStatusById(List<String> recordIds, Integer status) {
        return recordMapper.updateWinStatusById(recordIds, status, DateUtil.getCommonDate());
    }

    @Override
    public long updateWinnerMessage(SaveWinnerMessageParam param, boolean isArr) {
        AwardRecordEntity recordEntity = new AwardRecordEntity();
        recordEntity.setAwardPage(param.getAwardPage()).setStatus(RecordStatusEnum.YES.getIndex()).setPhone(param.getPhone());
        recordEntity.setName(param.getWinnerParam().getName()).setContactPhone(param.getWinnerParam().getContactPhone()).setUpdateTime(DateUtil.getCommonDate());
        if (Objects.nonNull(param.getWinnerParam().getAddress())) {
            recordEntity.setProvince(param.getWinnerParam().getAddress().getProvince())
                    .setCity(param.getWinnerParam().getAddress().getCity())
                    .setAddress(param.getWinnerParam().getAddress().getMore());
        }
        return recordMapper.updateWinnerMessage(recordEntity);
    }

    @Override
    public AwardRecordDO getRecordByIdsAndStatus(String awardId, String recordId, String deliverId, Integer status) {
        RecordQuery query = new RecordQuery();
        query.setRecordId(recordId).setAwardId(awardId).setStatus(status);
        query.setDeliverId(StringUtils.isNotBlank(deliverId) ? deliverId : null);
        return awardRecordEntityToDo(recordMapper.findOneByQueryParam(query));
    }

    @Override
    public PageDTO<AwardRecordDO> getRecordListByPage(GetWinnersParam param, PageParam pageParam) {
        PageDTO<AwardRecordDO> pageDTO = new PageDTO<>();
        RecordQuery query = new RecordQuery();
        query.setAwardId(param.getAwardId());
        query.setWinLevel((Objects.nonNull(param.getLevel()) && param.getLevel() == AwardLevelEnum.LEVEL_ALL.getIndex()) ? null : param.getLevel());
        query.setWinName(StringUtils.isNotBlank(param.getName()) ? param.getName() : null);
        query.setPhone(StringUtils.isNotBlank(param.getPhone()) ? param.getPhone() : null);
        query.setQueryStatus(param.getStatus());
        query.setDeliverSource(param.getDeliverSource());
        long total = recordMapper.getRecordTotal(query);
        pageDTO.setTotal(total);
        List<AwardRecordDO> recordDOList = new ArrayList<>();
        if (total > 0) {
            query.setSkip((pageParam.getPage() - 1) * pageParam.getSize());
            query.setSize(pageParam.getSize());
            List<AwardRecordEntity> recordList = recordMapper.findRecordList(query);
            if (!CollectionUtils.isEmpty(recordList)) {
                for (AwardRecordEntity recordEntity : recordList) {
                    recordDOList.add(awardRecordEntityToDo(recordEntity));
                }
            }
        }
        pageDTO.setData(recordDOList);
        return pageDTO;
    }

    @Override
    public PageDTO<AwardRecordDO> getRecordDetailByPage(ListWinnerDetailsParam param, PageParam pageParam, List<Integer> levelList) {
        List<AwardRecordDO> recordDOList = new ArrayList<>();
        if (CollectionUtils.isEmpty(levelList)) {
            return new PageDTO<>(recordDOList, 0L);
        }
        if (Objects.nonNull(param.getLevel()) && param.getLevel() != AwardLevelEnum.LEVEL_ALL.getIndex() && !levelList.contains(param.getLevel())) {
            return new PageDTO<>(recordDOList, 0L);
        }
        RecordQuery query = new RecordQuery();
        query.setAwardId(param.getAwardId()).setStatus(RecordStatusEnum.YES.getIndex());
        query.setWinName(StringUtils.isNotBlank(param.getName()) ? param.getName() : null);
        query.setDeliverId(StringUtils.isNotBlank(param.getDeliverId()) ? param.getDeliverId() : null);
        query.setWinLevel((Objects.nonNull(param.getLevel()) && param.getLevel() == AwardLevelEnum.LEVEL_ALL.getIndex()) ? null : param.getLevel());
        PageDTO<AwardRecordDO> pageDTO = new PageDTO<>();
        long total = recordMapper.getRecordDetailTotal(query, levelList);
        pageDTO.setTotal(total);
        if (total > 0) {
            query.setSkip((pageParam.getPage() - 1) * pageParam.getSize());
            query.setSize(pageParam.getSize());
            List<AwardRecordEntity> recordDetailList = recordMapper.findRecordDetailList(query, levelList);
            if (!CollectionUtils.isEmpty(recordDetailList)) {
                for (AwardRecordEntity recordEntity : recordDetailList) {
                    recordDOList.add(awardRecordEntityToDo(recordEntity));
                }
            }
        }
        pageDTO.setData(recordDOList);
        return pageDTO;
    }

    @Override
    public List<AwardRecordDO> getExportRecords(ExportWinnersParam param) {
        RecordQuery query = new RecordQuery();
        query.setAwardId(param.getAwardId())
                .setDeliverId(StringUtils.isNotBlank(param.getDeliverId()) ? param.getDeliverId() : null)
                .setWinLevel((Objects.nonNull(param.getLevel()) && param.getLevel() == AwardLevelEnum.LEVEL_ALL.getIndex()) ? null : param.getLevel())
                .setWinName(StringUtils.isNotBlank(param.getName()) ? param.getName() : null)
                .setPhone(StringUtils.isNotBlank(param.getPhone()) ? param.getPhone() : null)
                .setQueryStatus(param.getStatus())
                .setDeliverSource(param.getDeliverSource());
        List<AwardRecordEntity> recordList = recordMapper.findRecordList(query);
        List<AwardRecordDO> recordDOList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(recordList)) {
            for (AwardRecordEntity recordEntity : recordList) {
                recordDOList.add(awardRecordEntityToDo(recordEntity));
            }
        }
        return recordDOList;
    }

    @Override
    public List<AwardRecordDO> getExportRecordDetails(ExportWinnerDetailsParam param, List<Integer> levelList) {
        List<AwardRecordDO> recordDOList = new ArrayList<>();
        if (CollectionUtils.isEmpty(levelList)) {
            return recordDOList;
        }
        if (Objects.nonNull(param.getLevel()) && (param.getLevel() != AwardLevelEnum.LEVEL_ALL.getIndex()) && !levelList.contains(param.getLevel())) {
            return recordDOList;
        }
        RecordQuery query = new RecordQuery();
        query.setAwardId(param.getAwardId()).setStatus(RecordStatusEnum.YES.getIndex());
        query.setWinName(StringUtils.isNotBlank(param.getName()) ? param.getName() : null);
        query.setDeliverId(StringUtils.isNotBlank(param.getDeliverId()) ? param.getDeliverId() : null);
        query.setWinLevel((Objects.nonNull(param.getLevel()) && AwardLevelEnum.LEVEL_ALL.getIndex() == param.getLevel()) ? null : param.getLevel());
        List<AwardRecordEntity> recordDetailList = recordMapper.findRecordDetailList(query, levelList);
        if (!CollectionUtils.isEmpty(recordDetailList)) {
            for (AwardRecordEntity recordEntity : recordDetailList) {
                recordDOList.add(awardRecordEntityToDo(recordEntity));
            }
        }
        return recordDOList;
    }

    @Override
    public long getDrawCountByIdAndStatus(String awardId, String deliverId, Integer status) {
        return recordMapper.getDrawCountByIdAndStatus(awardId, StringUtils.isNotBlank(deliverId) ? deliverId : null, status);
    }

    @Override
    public List<AwardDetailDTO> getAwardDetailByAgg(String awardId, String deliverId, Integer status) {
        return recordMapper.getDrawDetail(awardId, StringUtils.isNotBlank(deliverId) ? deliverId : null, status);
    }

    @Override
    public AwardRecordDO getRecordByAwardPageAndStatus(String awardPage, Integer status) {
        RecordQuery query = new RecordQuery().setAwardPage(awardPage).setStatus(status);
        return awardRecordEntityToDo(recordMapper.findOneByQueryParam(query));
    }

    @Override
    public long updateRecordStatusByAwardPage(String awardPage, Integer status) {
        return recordMapper.updateStatusByAwardPage(awardPage, status, null, DateUtil.getCommonDate());
    }

    @Override
    public long updateRecordWinByAwardPage(String awardPage, AwardRecordDO.Win win) {
        AwardRecordEntity recordEntity = new AwardRecordEntity();
        recordEntity.setAwardPage(awardPage).setStatus(RecordStatusEnum.PASS.getIndex());
        recordEntity.setWinName(win.getName()).setWinLevel(win.getLevel()).setWinLevelName(win.getLevelStr()).setUpdateTime(DateUtil.getCommonDate())
                .setWinStatus(AwardIssueStatusEnum.TODO.getIndex()).setWinTime(DateUtil.getCommonDate()).setIssueType(win.getMethod()).setWinCode(win.getCode());
        if (log.isInfoEnabled()) {
            log.info("[award] 更新中奖信息:中奖信息:{}, 更新中奖记录:{}", JSON.toJSONString(win), JSON.toJSONString(recordEntity));
        }
        return recordMapper.updateRecordWinByAwardPage(recordEntity);
    }

    @Override
    public long updateStatusByAwardPageAndStatus(String awardPage, Integer status) {
        return recordMapper.updateStatusByAwardPage(awardPage, status, RecordStatusEnum.PASS.getIndex(), DateUtil.getCommonDate());
    }

    @Override
    public AwardRecordDO getRecordByPageAndPhone(String awardPage, String phone) {
        RecordQuery query = new RecordQuery().setAwardPage(awardPage).setPhone(phone);
        return awardRecordEntityToDo(recordMapper.findOneByQueryParam(query));
    }

    @Override
    public long getNoWinCountById(String awardId, String deliverId) {
        return recordMapper.getNoWinCountById(awardId, StringUtils.isNotBlank(deliverId) ? deliverId : null);
    }

    /**
     * AwardRecord数据转换
     *
     * @param recordEntity AwardRecordEntity
     * @return AwardRecordDO
     */
    private AwardRecordDO awardRecordEntityToDo(AwardRecordEntity recordEntity) {
        if (Objects.nonNull(recordEntity)) {
            AwardRecordDO recordDO = new AwardRecordDO();
            recordDO.setId(recordEntity.getRecordId());
            recordDO.setAwardId(recordEntity.getAwardId());
            recordDO.setPhone(recordEntity.getPhone());
            recordDO.setStatus(recordEntity.getStatus());
            recordDO.setName(recordEntity.getName());
            recordDO.setContactPhone(recordEntity.getContactPhone());
            recordDO.setCreateTime(recordEntity.getCreateTime());
            recordDO.setUpdateTime(recordEntity.getUpdateTime());
            // 奖励信息
            AwardRecordDO.Award award = new AwardRecordDO.Award();
            award.setAwardId(recordEntity.getAwardId());
            award.setDeliverId(recordEntity.getDeliverId());
            award.setDeliverSource(recordEntity.getDeliverSource());
            award.setDeliverName(recordEntity.getDeliverName());
            award.setSurveyId(recordEntity.getSurveyId());
            award.setSurveySeq(recordEntity.getSurveySeq());
            award.setAwardPage(recordEntity.getAwardPage());
            award.setPhone(recordEntity.getPhone());
            recordDO.setAward(award);
            if (recordEntity.getStatus() == RecordStatusEnum.YES.getIndex()) {
                // 中奖信息
                AwardRecordDO.Win win = new AwardRecordDO.Win();
                win.setName(recordEntity.getWinName());
                win.setLevel(recordEntity.getWinLevel());
                win.setCode(recordEntity.getWinCode());
                win.setStatus(recordEntity.getWinStatus());
                win.setMethod(recordEntity.getIssueType());
                win.setLevelStr(recordEntity.getWinLevelName());
                win.setWinTime(recordEntity.getWinTime());
                recordDO.setWin(win);
                // 地址信息
                AwardRecordDO.Address address = new AwardRecordDO.Address();
                address.setProvince(recordEntity.getProvince());
                address.setCity(recordEntity.getCity());
                address.setMore(recordEntity.getAddress());
                recordDO.setAddress(address);
            }
            return recordDO;
        }
        return null;
    }
}
